<?php

/**
 * Swoole Tcp Server here
 */
namespace App\Service\TcpServer;

use Hyperf\Contract\OnReceiveInterface;
use App\Service\Code\Normal;
use App\Model\PssLogModel\RpcMicroServiceLog;
class TcpServer implements OnReceiveInterface
{
    const SEND_BUFFER_LENGTH = 1024;
    const DELIMITER_REPLACE = "{{______\r\n\r\n______}}";//TCP 包体结束分隔符号
    protected $interface_code;
    public function onReceive($server, int $fd, int $fromId, string $body): void
    {
        $start  = microtime(true);
        $result = $this->runTcpService($body);
        //获取客户端请求信息
        $clientInfo     = $server->getClientInfo($fd);
        $remote_ip      = $clientInfo['remote_ip']??'0.0.0.0';
        $server_port    = $clientInfo['server_port']??'0.0.0.0';
        
        //只记录错误日志
        $rpc_debug      = env('RPC_DEBUG');
        if( $rpc_debug == true || $result['code'] != Normal::SUC )
        {
            $data = @json_decode(rawurldecode(base64_decode($body)),true);
            RpcMicroServiceLog::instance()->addLog([
                'interface_code'    => $this->interface_code,
                'request_url'       => $remote_ip . ':' . $server_port,
                'request_param'     => json_encode($data,JSON_UNESCAPED_UNICODE),
                'response_code'     => $result['code'] ?? 0 ,
                'response_data'     => json_encode($result,JSON_UNESCAPED_UNICODE),
                'req_used_time'     => bcsub(microtime(true), $start,3),
            ]);
        }
        $response = base64_encode(rawurlencode(json_encode($result,JSON_UNESCAPED_UNICODE)));
        $server->send($fd,$response."\n");
    }


    /**
     * 开始处理服务业务逻辑
     * @param string $body
     */
    public function runTcpService( string $body)
    {
        //反序列化数据
        $data = @json_decode(rawurldecode(base64_decode($body)),true);
        $interface_code         = $data['method'];
        $requestMethodsModule   = \explode(".",$interface_code);
        $this->interface_code   = $interface_code;
        $request_id             = $data['request_id'];
        
        if( count($requestMethodsModule) != 3 ) {
            return [
                'code'          => 500,
                'msg'           => "服务模块解析失败【{$interface_code}】，请检查服务模块格式是否正确!",
                'service'       => $interface_code,
                'request_id'    => $request_id,
            ];
        }
        
        //解析模块容器
        $service = $requestMethodsModule[0];
        $class   = $requestMethodsModule[1];
        $method  = $requestMethodsModule[2];
        
        //异常处理
        try 
        {
            //解析数据
            $message        = $data['argments'];
            $classService   = "App\\Service\\{$service}\\{$class}";
            $object = container()->get($classService);
            $result = $object->{$method}($message);
            $result = (array)$result;
            $result['request_id'] = $request_id;
            return $result;
        } 
        catch ( \Throwable $t ) 
        {
            return [
                'code'      => 500,
                'msg'       => "system happened error,please contact us manager!",
                'sub_msg'   => [
                    'errorMessage'  => $t->getMessage(),
                    'errorFile'     => $t->getFile(),
                    'errorLine'     => $t->getLine(),
                ],
                'service'       => $interface_code,
                'request_id'    => $request_id,
            ];
        }
    }
}